﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using DslModeling = global::Microsoft.VisualStudio.Modeling;
using devtm.Editor.TypeSelector.Types;

namespace devtm.Editor.TypeSelector
{
    public class SourceTypes : ITypeProvider
    {

        [ThreadStatic()]
        private static SourceTypes _sourceTypes;

        public static bool IsIntialized { get { return _sourceTypes != null; } }

        public SourceTypes()
        {

            if (_sourceTypes != null)
                throw new Exception("SourceTypes allready initialized");

            _sourceTypes = this;

            //Errors = new ContainerError();

        }

        [ThreadStatic()]
        private static List<ITypeProvider> source;
        public static List<ITypeProvider> Source { get { return source ?? (source = new List<ITypeProvider>()); } }
        

        public static T GetItem<T>() where T : ITypeProvider
        {

            //Errors.Clear();

            foreach (ITypeProvider item in Source)
            {
                if (item.GetType() == typeof(T))
                    return (T)item;
            }

            return (T)Activator.CreateInstance(typeof(T));

        }

        /// <summary>
        /// Removes the item.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        public static void RemoveItem<T>() where T : ITypeProvider, new()
        {

            //Errors.Clear();

            T i = default(T);

            foreach (ITypeProvider item in Source)
            {
                if (item.GetType() == typeof(T))
                    i = (T)item;
            }

            if (Equals(i, default(T)))
                Source.Remove(i);

        }

        public IEnumerable<Type> GetTypes(DslModeling.Store store, HashSet<String> namespaces)
        {

            //Errors.Clear();

            foreach (ITypeProvider item in Source)
                foreach (Type type in item.GetTypes(store, namespaces))
                    yield return type;

        }

        public IEnumerable<Type> GetTypes(DslModeling.Store store, HashSet<String> namespaces, Func<Type, bool> filter)
        {

            //Errors.Clear();

            foreach (ITypeProvider item in source)
                foreach (Type type in item.GetTypes(store, namespaces, filter))
                    yield return type;
        }

        #region Disposable

        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        ~SourceTypes()
        {
            Dispose(false);
        }

        // The bulk of the clean-up code is implemented in Dispose(bool)
        protected virtual void Dispose(bool disposing)
        {

            if (disposing)
            {
                // free managed resources
            
            }

            _sourceTypes = null;

        }

        #endregion


        #region Errors



        //public static ContainerError Errors { get; private set; } 

        #endregion

    }
}
